home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dvips / dvips.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-20  |  12.3 KB  |  406 lines

  1. /*
  2.  *   This is the main routine.
  3.  */
  4. #ifndef DEFRES
  5. #define DEFRES (300)
  6. #endif
  7. #ifndef DEFPFMT
  8. #define DEFPFMT "letter"
  9. #endif
  10.  
  11. #include "structures.h" /* The copyright notice in that file is included too! */
  12. /*
  13.  *   First we define some globals.
  14.  */
  15. fontdesctype *fonthead ;      /* list of all fonts mentioned so far */
  16. fontdesctype *curfnt ;        /* the currently selected font */
  17. sectiontype *sections ;       /* sections to process document in */
  18. Boolean manualfeed ;          /* manual feed? */
  19. Boolean compressed ;          /* compressed? */
  20. int collatedcopies = 1 ;      /* how many collated copies? */
  21. int sectioncopies = 1 ;       /* how many times to repeat each section? */
  22. shalfword linepos = 0 ;       /* where are we on the line being output? */
  23. integer maxpages ;            /* the maximum number of pages */
  24. Boolean notfirst ;            /* true if a first page was specified */
  25. Boolean sendcontrolD ;        /* should we send a control D at end? */
  26. integer firstpage ;           /* the number of the first page if specified */
  27. int numcopies ;               /* number of copies of each page to print */
  28. char *oname ;                 /* output file name */
  29. char *iname ;                 /* dvi file name */
  30. char strings[STRINGSIZE] ;    /* strings for program */
  31. char *nextstring, *maxstring ; /* string pointers */
  32. FILE *dvifile, *bitfile ;     /* dvi and output files */
  33. quarterword *curpos ;         /* current position in virtual character packet */
  34. quarterword *curlim ;         /* final byte in virtual character packet */
  35. fontmaptype *ffont ;          /* first font in current frame */
  36. real conv ;                   /* conversion ratio, pixels per DVI unit */
  37. real alpha ;                  /* conversion ratio, DVI unit per TFM unit */
  38. integer mag ;                 /* the magnification of this document */
  39. Boolean overridemag ;         /* substitute for mag value in DVI file? */
  40. int actualdpi = DEFRES ;      /* the actual resolution of the printer */
  41. int maxdrift ;                /* max pixels away from true rounded position */
  42. char *paperfmt = DEFPFMT ;    /* paper format */
  43. integer fontmem ;             /* memory remaining in printer */
  44. integer pagecount ;           /* page counter for the sections */
  45. integer pagenum ;             /* the page number we currently look at */
  46. long bytesleft ;              /* number of bytes left in raster */
  47. quarterword *raster ;         /* area for raster manipulations */
  48. integer hh, vv ;              /* horizontal and vertical pixel positions */
  49. char *tfmpath ;               /* pointer to directories for tfm files */
  50. char *pkpath ;                /* pointer to directories for pk files */
  51. char *vfpath ;                /* pointer to directories for vf files */
  52. char *figpath ;               /* pointer to directories for figure files */
  53. integer swmem ;               /* font memory in the PostScript printer */
  54. int quiet ;                   /* should we only print errors to stderr? */
  55. int filter ;                  /* act as filter default output to stdout,
  56.                                                default input to stdin? */
  57. int totalpages = 0 ;          /* total number of pages */
  58. Boolean reverse ;             /* are we going reverse? */
  59. Boolean usesPSfonts ;         /* do we use local PostScript fonts? */
  60. Boolean usesspecial ;         /* do we use \special? */
  61. Boolean headers_off ;         /* do we send headers or not? */
  62. char *headerfile ;            /* default header file */
  63. Boolean multiplesects ;       /* more than one section? */
  64. Boolean disablecomments ;     /* should we suppress any EPSF comments? */
  65. char *printer ;               /* what printer to send this to? */
  66. char *mfmode ;                /* default MF mode */
  67. frametype frames[MAXFRAME] ;  /* stack for virtual fonts */
  68.  
  69. #ifdef DEBUG
  70. integer debug_flag = 0;
  71. #endif /* DEBUG */
  72. /*
  73.  *   This routine calls the following externals:
  74.  */
  75. extern void outbangspecials() ;
  76. extern void prescanpages() ;
  77. extern void initprinter() ;
  78. extern void cleanprinter() ;
  79. extern void dosection() ;
  80. extern void getdefaults() ;
  81. extern void cmdout() ;
  82. extern void numout() ;
  83. extern void add_header() ;
  84. extern char *strcpy() ;
  85. /*
  86.  *   This error routine prints an error message; if the first
  87.  *   character is !, it aborts the job.
  88.  */
  89. static char *progname ;
  90. void
  91. error(s)
  92.     char *s ;
  93. {
  94.    (void)fprintf(stderr, "%s: %s\n", progname, s) ;
  95.    if (*s=='!') {
  96.       if (bitfile != NULL) {
  97.          cleanprinter() ;
  98.       }
  99.       exit(1) ; /* fatal */
  100.    }
  101. }
  102.  
  103. /*
  104.  *   Initialize sets up all the globals and data structures.
  105.  */
  106. void
  107. initialize()
  108. {
  109.    fonthead = NULL ;
  110.    sections = NULL ;
  111.    maxpages = 100000 ;
  112.    firstpage = 0 ;
  113.    notfirst = 0 ;
  114.    overridemag = 0 ;
  115.    numcopies = 1 ;
  116.    nextstring = strings ;
  117.    iname = strings ;
  118.    *nextstring++ = 0 ;
  119.    maxstring = strings + STRINGSIZE - 200 ;
  120.    bitfile = NULL ;
  121.    bytesleft = 0 ;
  122.    pkpath = PKPATH ;
  123.    vfpath = VFPATH ;
  124.    tfmpath = TFMPATH ;
  125.    figpath = FIGPATH ;
  126.    swmem = SWMEM ;
  127.    oname = OUTPATH ;
  128.    sendcontrolD = 0 ;
  129.    multiplesects = 0 ;
  130.    disablecomments = 0 ;
  131.    maxdrift = -1 ;
  132. }
  133. /*
  134.  *   This routine copies a string into the string `pool', safely.
  135.  */
  136. char *
  137. newstring(s)
  138.    char *s ;
  139. {
  140.    int l ;
  141.  
  142.    if (s == NULL)
  143.       return(NULL) ;
  144.    l = strlen(s) ;
  145.    if (nextstring + l >= maxstring)
  146.       error("! out of string space") ;
  147.    (void)strcpy(nextstring, s) ;
  148.    s = nextstring ;
  149.    nextstring += l + 1 ;
  150.    return(s) ;
  151. }
  152. /*
  153.  *   Finally, our main routine.
  154.  */
  155. main(argc, argv)
  156.     int argc ;
  157.     char *argv[] ;
  158. {
  159.    int i, lastext = -1 ;
  160.    register sectiontype *sects ;
  161.    char *getenv();
  162.  
  163.    progname = argv[0] ;
  164.    initialize() ;
  165.  
  166.    printer = getenv("PRINTER");
  167.    getdefaults("ps") ;
  168.    if(printer)
  169.       getdefaults(printer);
  170.  
  171. /*
  172.  *   This next whole big section of code is straightforward; we just scan
  173.  *   the options.  An argument can either immediately follow its option letter
  174.  *   or be separated by spaces.  Any argument not preceded by '-' and an
  175.  *   option letter is considered a file name; the program complains if more
  176.  *   than one file name is given, and uses stdin if none is given.
  177.  */
  178.    for (i=1; i<argc; i++) {
  179.       if (*argv[i]=='-') {
  180.          char *p=argv[i]+2 ;
  181.          char c=argv[i][1] ;
  182.          switch (c) {
  183. case 'c' :
  184.             if (*p == 0 && argv[i+1])
  185.                p = argv[++i] ;
  186.             if (sscanf(p, "%d", &numcopies)==0)
  187.                error("! Bad number of copies option (-c).") ;
  188.             break ;
  189. #ifdef DEBUG
  190. case 'd' :
  191.         if (*p == 0 && argv[i+1])
  192.            p = argv[++i];
  193.         if (sscanf(p, "%d", &debug_flag)==0)
  194.            error("! Bad debug option (-d).");
  195.         break;
  196. #endif /* DEBUG */
  197. case 'e' :
  198.             if (*p == 0 && argv[i+1])
  199.                p = argv[++i] ;
  200.             if (sscanf(p, "%d", &maxdrift)==0 || maxdrift<0)
  201.                error("! Bad maxdrift option (-e).") ;
  202.             break ;
  203. case 'f' :
  204.             filter = (*p != '0') ;
  205.             if (filter)
  206.                oname = "" ;
  207.             break ;
  208. case 'h' : case 'H' :
  209.             if (*p == 0 && argv[i+1])
  210.                p = argv[++i] ;
  211.             if (strcmp(p, "-") == 0)
  212.                headers_off = 1 ;
  213.             else
  214.                add_header(p) ;
  215.             break ;
  216. case 'm' :
  217.             manualfeed = (*p != '0') ;
  218.             break ;
  219. case 'n' :
  220.             if (*p == 0 && argv[i+1])
  221.                p = argv[++i] ;
  222. #ifdef SHORTINT
  223.             if (sscanf(p, "%ld", &maxpages)==0)
  224. #else    /* ~SHORTINT */
  225.             if (sscanf(p, "%d", &maxpages)==0)
  226. #endif    /* ~SHORTINT */
  227.                error("! Bad number of pages option (-n).") ;
  228.             break ;
  229. case 'o' : case 'O' :
  230.             if (*p == 0 && argv[i+1] && *argv[i+1]!='-')
  231.                p = argv[++i] ;
  232.             oname = p ;
  233.             break ;
  234. case 'p' :
  235.             if (*p == 0 && argv[i+1])
  236.                p = argv[++i] ;
  237. #ifdef SHORTINT
  238.             if (sscanf(p, "%ld", &firstpage)==0)
  239. #else    /* ~SHORTINT */
  240.             if (sscanf(p, "%d", &firstpage)==0)
  241. #endif    /* ~SHORTINT */
  242.                error("! Bad first page option (-p).") ;
  243.             notfirst = 1 ;
  244.             break ;
  245. case 'q' : case 'Q' :
  246.             quiet = (*p != '0') ;
  247.             break ;
  248. case 'r' :
  249.             reverse = (*p != '0') ;
  250.             break ;
  251. case 't' :
  252.             if (*p == 0 && argv[i+1])
  253.                p = argv[++i] ;
  254.             paperfmt = p ;
  255.             break ;
  256. case 'x' :
  257.             if (*p == 0 && argv[i+1])
  258.                p = argv[++i] ;
  259.             if (sscanf(p, "%d", &mag)==0 || mag < 10 ||
  260.                        mag > 100000)
  261.                error("! Bad magnification parameter (-x).") ;
  262.             overridemag = 1 ;
  263.             break ;
  264. case 'C' :
  265.             if (*p == 0 && argv[i+1])
  266.                p = argv[++i] ;
  267.             if (sscanf(p, "%d", &collatedcopies)==0)
  268.                error("! Bad number of collated copies option (-C).") ;
  269.             break ;
  270. case 'D' :
  271.             if (*p == 0 && argv[i+1])
  272.                p = argv[++i] ;
  273.             if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  274.                        actualdpi > 10000)
  275.                error("! Bad dpi parameter (-D).") ;
  276.             break ;
  277. case 'F' :
  278.             sendcontrolD = (*p != '0') ;
  279.             break ;
  280. case 'N' :
  281.             disablecomments = (*p != '0') ;
  282.             break ;
  283. case 'P' :
  284.             if (*p == 0 && argv[i+1])
  285.                p = argv[++i] ;
  286.             printer = p ;
  287.         getdefaults("ps") ;
  288.         getdefaults(printer);
  289.             break ;
  290. case 'R' :
  291.             reverse = 0 ;
  292.             break ;
  293. case 'Z' :
  294.             compressed = (*p != '0') ;
  295.             break ;
  296. case '?' :
  297.             (void)fprintf(stderr, BANNER) ;
  298.             break ;
  299. default:
  300.             error("! Bad option, not one of cefhmnopqrtxCDFNPZ?") ;
  301.          }
  302.       } else {
  303.          if (*iname == 0) {
  304.             register char *p ;
  305.  
  306.             lastext = 0 ;
  307.             iname = nextstring ;
  308.             p = argv[i] ;
  309.             while (*p) {
  310.                *nextstring = *p++ ;
  311.                if (*nextstring == '.')
  312.                   lastext = nextstring - iname ;
  313.                else if (*nextstring == '/' || *nextstring == ':')
  314.                   lastext = 0 ;
  315.                nextstring++ ;
  316.             }
  317.             if (lastext == 0) {
  318.                lastext = nextstring - iname ;
  319.                *nextstring++ = '.' ;
  320.                *nextstring++ = 'd' ;
  321.                *nextstring++ = 'v' ;
  322.                *nextstring++ = 'i' ;
  323.             }
  324.             *nextstring++ = 0 ;
  325.          } else
  326.             error("! Two input file names specified.") ;
  327.       }
  328.    }
  329.  
  330.    if (!quiet)
  331.       (void)fprintf(stderr, BANNER) ;
  332.    if (*oname == 0 && ! filter) {
  333.       oname = nextstring ;
  334.       for (i=0; i<=lastext; i++)
  335.          *nextstring++ = iname[i] ;
  336.       *nextstring++ = 'p' ;
  337.       *nextstring++ = 's' ;
  338.       *nextstring++ = 0 ;
  339.    }
  340. #ifdef DEBUG
  341.    if (dd(D_PATHS)) {
  342. #ifdef SHORTINT
  343.     (void)fprintf(stderr,"input file %s output file %s swmem %ld\n",
  344. #else /* ~SHORTINT */
  345.        (void)fprintf(stderr,"input file %s output file %s swmem %d\n",
  346. #endif /* ~SHORTINT */
  347.            iname, oname, swmem) ;
  348.    (void)fprintf(stderr,"tfm path %s pk path %s\n", tfmpath, pkpath) ;
  349.    } /* dd(D_PATHS) */
  350. #endif /* DEBUG */
  351. /*
  352.  *   Now we try to open the dvi file.
  353.  */
  354.    headerfile = (compressed? CHEADERFILE : HEADERFILE) ;
  355.    add_header(headerfile) ;
  356.    if (*iname != 0)
  357.       dvifile = fopen(iname, "r") ;
  358.    else if (filter)
  359.       dvifile = stdin;
  360.    else
  361.       error("! No input filename supplied.") ;
  362.    if (dvifile==NULL)
  363.       error("! DVI file can't be opened.") ;
  364. /*
  365.  *   Now we do our main work.
  366.  */
  367.    if (maxdrift < 0) {
  368.       if (actualdpi <= 599)
  369.          maxdrift = actualdpi / 100 ;
  370.       else if (actualdpi < 1199)
  371.          maxdrift = actualdpi / 200 + 3 ;
  372.       else
  373.          maxdrift = actualdpi / 400 + 6 ;
  374.    }
  375.    prescanpages() ;
  376.    if (usesPSfonts)
  377.       add_header(PSFONTHEADER) ;
  378.    if (usesspecial)
  379.       add_header(SPECIALHEADER) ;
  380.    sects = sections ;
  381.    if (sects == NULL || sects->next == NULL) {
  382.       sectioncopies = collatedcopies ;
  383.       collatedcopies = 1 ;
  384.    } else {
  385.       totalpages *= collatedcopies ;
  386.       multiplesects = 1 ;
  387.    }
  388.    initprinter() ;
  389.    outbangspecials() ;
  390.    for (i=0; i<collatedcopies; i++) {
  391.       sects = sections ;
  392.       while (sects != NULL) {
  393.          if (! quiet)
  394.             (void)fprintf(stderr, ". ") ;
  395.          (void)fflush(stderr) ;
  396.          dosection(sects, sectioncopies) ;
  397.          sects = sects->next ;
  398.       }
  399.    }
  400.    cleanprinter() ;
  401.    if (! quiet)
  402.       (void)fprintf(stderr, "\n") ;
  403.    exit(0) ;
  404.    /*NOTREACHED*/
  405. }
  406.